using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using MathNet.Numerics.LinearAlgebra;
using System.Drawing;
using System.Drawing.Imaging;
using System.Windows.Forms;

namespace ImgProcessGui
{
    class ImageFunctions
    {

        
        /// <summary>
        /// The patches are taken left2right
        /// Taking patches with no overlap
        /// </summary>
        /// <param name="bmp"></param>
        /// <param name="sizeOfPatch"></param>
        /// <returns></returns>
        public byte[] BitMap2Bytes(ref Bitmap bmp, int sizeOfPatch)
        {
            unsafe
            {

                //This Byte Array will hold our words;
                //int x=0, y=0;
                int index = 0;
                int byteIndex = 0;
                // Lock the bitmap data to a fixed position  
                // We only Read data so we use ReadOnly 
                BitmapData bmData = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.ReadOnly, PixelFormat.Format8bppIndexed);
                byte[] patch = new byte[bmData.Height * bmData.Width];
                try
                {
                    for (int patch_row = 0; patch_row <= (bmData.Height - sizeOfPatch); patch_row = patch_row + sizeOfPatch)
                    {
                        for (int patch_col = 0; patch_col <= (bmData.Width - sizeOfPatch); patch_col = patch_col + sizeOfPatch)
                        {
                            //index = (patch_row * bmData.Stride) + (patch_col / 8);
                            // Get a pointer to the beginning of the patch data 
                            //byte* ptr = (byte*)(bmData.Scan0) + index;
                            int current_row = patch_row - 1;
                            for (int row = 0; row < sizeOfPatch; row++)
                            {
                                index = ((++current_row) * bmData.Stride) + patch_col;
                                byte* ptr = (byte*)(bmData.Scan0) + index;
                                for (int col = 0; col < sizeOfPatch; col++)
                                {
                                    patch[byteIndex] = ptr[col];
                                    byteIndex++;
                                }

                            }
                        }
                    }

                    bmp.UnlockBits(bmData);
                }
                catch
                {
                    bmp.UnlockBits(bmData);
                    MessageBox.Show("BitMap2Bytes - Error");
                }
                return patch;
            }//end of unsafe code
        }
                
        /// <summary>
        /// The patches are taken left2right
        /// Patches are taken with overlap according to jump
        /// </summary>
        /// <param name="bmp"></param>
        /// <param name="sideOfPatch"></param>
        /// <param name="jump"></param>
        /// <returns></returns>
        public byte[] BitMap2Bytes(ref Bitmap bmp, int sideOfPatch,int jump)
        {
            unsafe
            {

                //This Byte Array will hold our words;
                //int x=0, y=0;
                int index = 0;
                int byteIndex = 0;
                // Lock the bitmap data to a fixed position  
                // We only Read data so we use ReadOnly 
                BitmapData bmData = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.ReadOnly, PixelFormat.Format8bppIndexed);
                byte[] patch;
                patch = new byte[(((bmp.Width - sideOfPatch) / jump) + 1) * (((bmp.Height - sideOfPatch) / jump) + 1) * sideOfPatch * sideOfPatch];
                
                try
                {
                    for (int patch_row = 0; patch_row <= (bmData.Height - sideOfPatch); patch_row = patch_row + jump)
                    {
                        for (int patch_col = 0; patch_col <= (bmData.Width - sideOfPatch); patch_col = patch_col + jump)
                        {
                     
                            int current_row = patch_row - 1;
                            for (int row = 0; row < sideOfPatch; row++)
                            {
                                index = ((++current_row) * bmData.Stride) + patch_col;
                                byte* ptr = (byte*)(bmData.Scan0) + index;
                                for (int col = 0; col < sideOfPatch; col++)
                                {
                                    patch[byteIndex] = ptr[col];
                                    byteIndex++;
                                }

                            }
                        }
                    }

                    bmp.UnlockBits(bmData);
                }
                catch
                {
                    bmp.UnlockBits(bmData);
                    MessageBox.Show("BitMap2Bytes - Error!");
                }
                return patch;
            }//end of unsafe code

        }
        
        /// <summary>
        /// Convert Bitmap to byte array from left to right
        /// </summary>
        /// <param name="bmp"></param>
        /// <returns></returns>
        public byte[] BitMap2SequenceByteArray(ref Bitmap bmp)
        {
            unsafe
            {

                //This Byte Array will hold our words;
                int byteIndex = 0;
                // Lock the bitmap data to a fixed position  
                // We only Read data so we use ReadOnly 
                BitmapData bmData = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.ReadOnly, PixelFormat.Format8bppIndexed);
                byte[] byteArray = new byte[bmData.Height * bmData.Width];
                try
                {
                            for (int y = 0; y < bmp.Height; y++)
                            {

                                byte* ptr = (byte*)bmData.Scan0 + (y * bmData.Stride);

                                for (int x = 0; x < bmp.Width; x++)
                                {

                                    byteArray[byteIndex] = ptr[x];
                                    byteIndex++;

                                }

                            }


                    bmp.UnlockBits(bmData);
                }
                catch
                {
                    bmp.UnlockBits(bmData);
                }
                return byteArray;
            }//end of unsafe code

        }

        /// <summary>
        /// Convert byte array to bitmap (from left to right)
        /// </summary>
        /// <param name="byteArray"></param>
        /// <param name="width">like original</param>
        /// <param name="height">like original</param>
        /// <returns></returns>
        public Bitmap SequenceByteArray2Bitmap(byte[] byteArray,int width,int height)
        {
            unsafe
            {
                Bitmap bmp = new Bitmap(width, height,PixelFormat.Format8bppIndexed);
                //This Byte Array will hold our words;
                int byteIndex = 0;
                // Lock the bitmap data to a fixed position  
                // We only Read data so we use ReadOnly 
                BitmapData bmData = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.ReadOnly, PixelFormat.Format8bppIndexed);
                
                try
                {
                    for (int y = 0; y < bmp.Height; y++)
                    {

                        byte* ptr = (byte*)bmData.Scan0 + (y * bmData.Stride);

                        for (int x = 0; x < bmp.Width; x++)
                        {

                            ptr[x] = byteArray[byteIndex];
                            byteIndex++;

                        }

                    }


                    bmp.UnlockBits(bmData);
                }
                catch
                {
                    bmp.UnlockBits(bmData);
                    MessageBox.Show("BitMap2Bytes - Error!");
                }
                SetColorPaletteGS(bmp);
                return bmp;
            }//end of unsafe code

        }

        /// <summary>
        /// 1 patch to bmp
        /// Works only for squered patch
        /// </summary>
        /// <param name="patch"></param>
        /// <returns></returns>
        public Bitmap ByteArray2Bmp(byte[] patch)
        {

            Bitmap bmp = new Bitmap((int)Math.Sqrt(patch.Length), (int)Math.Sqrt(patch.Length), PixelFormat.Format8bppIndexed);
            unsafe
            {
                // Lock the bitmap data to a fixed position
                // Only write data - WriteOnly
                BitmapData bmData = bmp.LockBits(
                    new Rectangle(0, 0, bmp.Width, bmp.Height),
                    ImageLockMode.WriteOnly,
                    PixelFormat.Format8bppIndexed);
                // Get a pointer to the beginning of the pixel data
                byte* p = (byte*)bmData.Scan0;

                // Since a Bitmap scan line is ALWAYS multiples of
                // 4 bytes we need to 'step over' the unused bytes
                // at the end.
                // Stride tells us the size of the scan line

                int diff = bmData.Stride - bmp.Width;

                // Loop through your array and add each byte	
                // For each loop increment the pointer by 1
                // When we reach the end of a line step over
                // the unused bytes

                for (int i = 0; i < patch.Length; i++)
                {
                    *p++ = patch[i];
                    if (i % bmp.Width == 0 && i > 0)
                        p += diff;
                }

                // Release the memory

                bmp.UnlockBits(bmData);
            }

            SetColorPaletteGS(bmp);

            return (bmp);
        }

        /// <summary>
        /// Set for greyscale
        /// </summary>
        /// <param name="bmp"></param>
        private static void SetColorPaletteGS(Bitmap bmp)
        {
            ColorPalette cp = bmp.Palette;
            for (int i = 0; i < cp.Entries.Length; i++)
            {

                cp.Entries[i] = Color.FromArgb(i, i, i);

            }
            bmp.Palette = cp;
        }

        /// <summary>
        /// Takes Matrix with doubles and convert it to byte array col after col
        /// </summary>
        /// <param name="mat"></param>
        /// <returns></returns>
        public byte[] Matrix2Byte(Matrix mat)
        {
            mat.Transpose();
            double[] dblArray = new double[mat.RowCount * mat.ColumnCount];
            double[][] data = mat.CopyToJaggedArray();
            int offset = 0;
            for (int i = 0; i < mat.RowCount; i++)
            {
                Buffer.BlockCopy(data[i], 0, dblArray, offset * sizeof(double), (mat.ColumnCount) * sizeof(double));
                offset = offset + mat.ColumnCount;
            }
            byte[] byteArray = new byte[dblArray.Length];
            for (int i = 0; i < dblArray.Length; i++)
            {
                byteArray[i] = (byte)dblArray[i];
            }
            return byteArray;
        }

        /// <summary>
        /// Take patches, each one in the size of single_patch_dim*single_patch_dim and
        /// creates a Bitmap containning the patches from right to left and then moves
        /// to the next row - TODO - Need Fix:see function for details (supports only dictionary of (patch_dim*patch_dim) size 
        /// </summary>
        /// <param name="patches"></param>
        /// <param name="single_patch_dim"></param>
        /// <returns></returns>
        public Bitmap CreateBMPDictionary(byte[] patches, int single_patch_dim)
        {
            //int numOfPatches = patches.Length / (single_patch_dim * single_patch_dim);
            int bitmap_w = single_patch_dim * single_patch_dim; //TODO - Change Rule so its fits to general Dictionary ant not only patch of 100 and maximum 100 patches in dictionary
            int bitmap_h = single_patch_dim * single_patch_dim;
            Bitmap bmp = new Bitmap(bitmap_w, bitmap_h, PixelFormat.Format8bppIndexed);

            unsafe
            {

                //This Byte Array will hold our words;
                //int x=0, y=0;
                int index = 0;
                int byteIndex = 0;
                // Lock the bitmap data to a fixed position  
                // We only Read data so we use ReadOnly 
                BitmapData bmData = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.ReadOnly, PixelFormat.Format8bppIndexed);
                try
                {
                    for (int patch_row = 0; patch_row <= (bmData.Height - single_patch_dim); patch_row = patch_row + single_patch_dim)
                    {
                        for (int patch_col = 0; patch_col <= (bmData.Width - single_patch_dim); patch_col = patch_col + single_patch_dim)
                        {
                            //index = (patch_row * bmData.Stride) + (patch_col / 8);
                            // Get a pointer to the beginning of the patch data 
                            //byte* ptr = (byte*)(bmData.Scan0) + index;
                            int current_row = patch_row - 1;
                            for (int row = 0; row < single_patch_dim; row++)
                            {
                                index = ((++current_row) * bmData.Stride) + patch_col;
                                byte* ptr = (byte*)(bmData.Scan0) + index;
                                for (int col = 0; col < single_patch_dim; col++)
                                {
                                    if (byteIndex < patches.Length)
                                    {
                                        ptr[col] = patches[byteIndex];
                                        byteIndex++;
                                    }
                                    else
                                    {
                                        ptr[col] = 255;
                                    }
                                }

                            }
                        }
                    }

                    bmp.UnlockBits(bmData);
                }
                catch
                {
                    bmp.UnlockBits(bmData);
                }

            }
            SetColorPaletteGS(bmp);
            return bmp;

        }

        /// <summary>
        /// Bytes ordered by patches left to right
        /// </summary>
        /// <param name="patches"></param>
        /// <param name="single_patch_dim"></param>
        /// <param name="bitmap_w"></param>
        /// <param name="bitmap_h"></param>
        /// <returns></returns>
        public Bitmap Bytes2Bitmap(byte[] patches, int single_patch_dim, int bitmap_w, int bitmap_h)
        {
            //int numOfPatches = patches.Length / (single_patch_dim * single_patch_dim);
            Bitmap bmp = new Bitmap(bitmap_w, bitmap_h, PixelFormat.Format8bppIndexed);

            unsafe
            {

                int index = 0;
                int byteIndex = 0;
                // Lock the bitmap data to a fixed position  
                // We only Read data so we use ReadOnly 
                BitmapData bmData = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.ReadOnly, PixelFormat.Format8bppIndexed);
                try
                {
                    for (int patch_row = 0; patch_row <= (bmData.Height - single_patch_dim); patch_row = patch_row + single_patch_dim)
                    {
                        for (int patch_col = 0; patch_col <= (bmData.Width - single_patch_dim); patch_col = patch_col + single_patch_dim)
                        {
                         
                            int current_row = patch_row - 1;
                            for (int row = 0; row < single_patch_dim; row++)
                            {
                                index = ((++current_row) * bmData.Stride) + patch_col;
                                byte* ptr = (byte*)(bmData.Scan0) + index;
                                for (int col = 0; col < single_patch_dim; col++)
                                {
                              
                                        ptr[col] = patches[byteIndex];
                                        byteIndex++;                              
                              
                                }

                            }
                        }
                    }

                    bmp.UnlockBits(bmData);
                }
                catch
                {
                    bmp.UnlockBits(bmData);
                }

            }
            SetColorPaletteGS(bmp);
            return bmp;
            
        }
       
        /// <summary>
        /// Get partchs from all pitures in directory - TODO - Check
        /// </summary>
        /// <param name="directoryToReadFrom"></param>
        /// <param name="patchSize"></param>
        /// <param name="jmpSize"></param>
        /// <returns></returns>
        public byte[] getPicturesPatches(String directoryToReadFrom, int patchSize, int jmpSize,out Matrix data_GreyScale,out Matrix data_RGB_PatchAvg )
        {
            bool flag_FirstTimeData = true;
            // check the direcotry existance
            if (Directory.Exists(directoryToReadFrom))
            {
                data_GreyScale = new Matrix(1, 1);
                data_RGB_PatchAvg = new Matrix(1,1);
                String[] files = Directory.GetFiles(directoryToReadFrom,"*.bmp");
                ImageFunctions imageFunc = new ImageFunctions();
                byte[] patches = null;
                //iterating over the files
                for (int i = 0; i < files.Length; i++)
                {
                    int newSize =0;
                    // creating a bitmap from the file
                    Bitmap img = new Bitmap(files[i]);

                    byte[] tmp;
                    Matrix RGB_PatchAvg_Mat;
                    Matrix GreyScale_Mat;
                   
                    if (GuiParameters.isRGB)
                    {
                        tmp = imageFunc.BitMap2Bytes24RGB(ref img, patchSize, jmpSize,out GreyScale_Mat,out RGB_PatchAvg_Mat);
                        if (!flag_FirstTimeData)
                        {
                            data_GreyScale = MatrixFunctions.GlueMatrixSideBySide(data_GreyScale, GreyScale_Mat);
                            data_RGB_PatchAvg = MatrixFunctions.GlueMatrixSideBySide(data_RGB_PatchAvg, RGB_PatchAvg_Mat);
                        }
                        else
                        {
                            data_GreyScale = GreyScale_Mat;
                            data_RGB_PatchAvg = RGB_PatchAvg_Mat;
                            flag_FirstTimeData = false;
                        }                     
                    }
                    else
                    {
                        tmp = imageFunc.BitMap2Bytes(ref img, patchSize, jmpSize);
                    }

                    
                   
                    #region For GreyPictures
                    if (!GuiParameters.isRGB)
                    {
                        byte[] tmpPatches = patches;
                        if (tmp != null)
                            newSize += tmp.Length;
                        if (tmpPatches != null)
                            newSize += tmpPatches.Length;
                        patches = new byte[newSize];
                        if (tmpPatches != null)
                        {
                            tmpPatches.CopyTo(patches, 0);
                        }

                        if (tmp != null)
                        {
                            int dest = (tmpPatches == null) ? 0 : tmpPatches.Length;
                            tmp.CopyTo(patches, dest);
                        }
                    }
                    #endregion

                }
                return patches;
            }
            else
            {
                data_GreyScale = new Matrix(1, 1);
                data_RGB_PatchAvg = new Matrix(1, 1);
                return null;
                
            }
        }

    

        #region 24RGB


        public Bitmap CreateBMPDictionaryRGB(byte[] patches, int single_patch_dim)
        {
            //int numOfPatches = patches.Length / (single_patch_dim * single_patch_dim);
            int bitmap_w = 100; //TODO - Change Rule so its fits to general Dictionary ant not only patch of 100 and maximum 100 patches in dictionary
            int bitmap_h = 100;
            Bitmap bmp = new Bitmap(bitmap_w, bitmap_h, PixelFormat.Format24bppRgb);
            unsafe
            {

                int index = 0;
                int byteIndex = 0;
                // Lock the bitmap data to a fixed position  
                // We only Read data so we use ReadOnly 
                BitmapData bmData = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);
                //byte[] patch;
                //patch = new byte[((((bmp.Width - single_patch_dim) / jump) + 1) * (((bmp.Height - single_patch_dim) / jump) + 1) * single_patch_dim * single_patch_dim) * 3];

                try
                {
                    for (int patch_row = 0; patch_row <= (bmData.Height - single_patch_dim); patch_row = patch_row + single_patch_dim)
                    {
                        for (int patch_col = 0; patch_col <= (bmData.Width - single_patch_dim); patch_col = patch_col + single_patch_dim)
                        {

                            int current_row = patch_row - 1;
                            for (int row = 0; row < single_patch_dim; row++)
                            {
                                index = ((++current_row) * bmData.Stride) + patch_col * 3;
                                byte* ptr = (byte*)(bmData.Scan0) + index;
                                for (int col = 0; col < single_patch_dim; col++)
                                {
                                    if (byteIndex < patches.Length)
                                    {
                                        ptr[col * 3] = patches[byteIndex];
                                        ptr[col * 3 + 1] = patches[byteIndex + 1];
                                        ptr[col * 3 + 2] = patches[byteIndex + 2];
                                        byteIndex = byteIndex + 3;
                                    }
                                    else
                                    {
                                        ptr[col * 3] = 255;
                                        ptr[col * 3 + 1] = 255;
                                        ptr[col * 3 + 2] = 255;
                                    }
                                    
                                }

                            }
                        }
                    }

                    bmp.UnlockBits(bmData);
                }
                catch
                {
                    bmp.UnlockBits(bmData);
                    MessageBox.Show("BitMap2Bytes - Error!");
                }
                return bmp;
            }//end of unsafe code

        }
        /// <summary>
        /// Returns parsed patch as bytes
        /// </summary>
        /// <param name="bmp"></param>
        /// <param name="sideOfPatch">patch must be square</param>
        /// <param name="jump">jump between patches</param>
        /// <param name="R">Red Vector</param>
        /// <param name="G">Green Vector</param>
        /// <param name="B">Blue Vector</param>
        /// <returns></returns>
        public byte[] BitMap2Bytes24RGB(ref Bitmap bmp, int sideOfPatch, int jump, out Matrix GreyScale_Mat, out Matrix RGB_PatchAvg_Mat)
        {
            unsafe
            {

                //This Byte Array will hold our words;
                //int x=0, y=0;
                int index = 0;
                int byteIndex = 0;
                // Lock the bitmap data to a fixed position  
                // We only Read data so we use ReadOnly 
                BitmapData bmData = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);
                byte[] patch;
                int NumOfBytesPatches =((((bmp.Width - sideOfPatch) / jump) + 1) * (((bmp.Height - sideOfPatch) / jump) + 1) * sideOfPatch * sideOfPatch)*3;
                patch = new byte[NumOfBytesPatches];
                byte[] R=new byte[patch.Length/3];
                byte[] G = new byte[patch.Length / 3];
                byte[] B = new byte[patch.Length / 3];
                byte[] GreyPatches = new byte[patch.Length / 3];
                int ColorMatrixCounter = 0;

                try
                {
                    for (int patch_row = 0; patch_row <= (bmData.Height - sideOfPatch); patch_row = patch_row + jump)
                    {
                        for (int patch_col = 0; patch_col <= (bmData.Width - sideOfPatch); patch_col = patch_col + jump)
                        {

                            int current_row = patch_row - 1;
                            for (int row = 0; row < sideOfPatch; row++)
                            {
                                index = ((++current_row) * bmData.Stride) + patch_col*3;
                                byte* ptr = (byte*)(bmData.Scan0) + index;
                                for (int col = 0; col < sideOfPatch; col++)
                                {
                                    patch[byteIndex] = ptr[col*3];
                                    R[ColorMatrixCounter] = ptr[col * 3];
                                    patch[byteIndex+1] = ptr[col * 3 + 1];
                                    G[ColorMatrixCounter] = ptr[col * 3 + 1];
                                    patch[byteIndex+2] = ptr[col * 3 + 2];
                                    B[ColorMatrixCounter] = ptr[col * 3 + 2];
                                    GreyPatches[ColorMatrixCounter] = (byte)((R[ColorMatrixCounter] + G[ColorMatrixCounter] + B[ColorMatrixCounter])/3);
                                    //Increase Counters
                                    byteIndex = byteIndex+3;
                                    ColorMatrixCounter++;
                                }

                            }//end of 1 patch

                        }
                    }

                    bmp.UnlockBits(bmData);
                }
                catch
                {
                    bmp.UnlockBits(bmData);
                    MessageBox.Show("BitMap2Bytes - Error!");
                }
                
                //Parsing Data into vertical matrix
                int numOfPatches = NumOfBytesPatches / (sideOfPatch * sideOfPatch*3);
                RGB_PatchAvg_Mat = new Matrix(3,numOfPatches);
                //GreyScale_Mat = new Matrix(sideOfPatch * sideOfPatch, numOfPatches);
                byte[] avgRGB = new byte[NumOfBytesPatches / 3];
                int j;
                for (int i = 0; i < (NumOfBytesPatches / 3); i++)
                {
                    j = i / (sideOfPatch * sideOfPatch);
                    //Red
                    RGB_PatchAvg_Mat[0, j] = RGB_PatchAvg_Mat[0, j] + (double)R[i] / (double)(sideOfPatch * sideOfPatch);
                    //Green
                    RGB_PatchAvg_Mat[1, j] = RGB_PatchAvg_Mat[1, j] + (double)G[i] / (double)(sideOfPatch * sideOfPatch);
                    //Blue
                    RGB_PatchAvg_Mat[2, j] = RGB_PatchAvg_Mat[2, j] + (double)B[i] / (double)(sideOfPatch * sideOfPatch);
                    //This vector holds the avg RGB of each Pixel
                    avgRGB[i] = (byte)((double)(R[i] + G[i] + B[i])/3);
                }
                GreyScale_Mat=MatrixFunctions.matConvertArr2Mat(avgRGB, 100);
                
                    return patch;
            }//end of unsafe code

        }

       

        #endregion


        #region Debug

        /// <summary>
        /// For Debug only- see function
        /// </summary>
        /// <param name="patchSelect"></param>
        /// <returns></returns>
        private static byte[] CreateTestPatchToImplement(int patchSelect)
        {
            Random rnd = new Random();
            byte[] byteToImplement;
            byte[] b = new byte[100];
            byte[] a = new byte[100];
            for (int i = 0; i < 100; i++)
            {
                b[i] = 0;
                a[i] = (byte)(rnd.Next(200, 255));
            }
            switch (patchSelect)
            {

                case 1:
                    byte[] byte1 = new byte[100] 
                    {
                        a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9],
                        a[10],a[11],a[12],a[13],b[14],b[15],b[16],a[17],a[18],a[19],
                        a[20],a[21],a[22],a[23],b[24],a[25],a[26],b[27],a[28],a[29],
                        a[30],a[31],a[32],b[33],a[34],a[35],a[36],a[37],b[38],a[39],
                        a[40],a[41],a[42],b[43],b[44],b[45],b[46],b[47],b[48],a[49],
                        a[50],a[51],a[52],b[53],a[54],a[55],a[56],a[57],b[58],a[59],
                        a[60],a[61],a[62],b[63],a[64],a[65],a[66],a[67],b[68],a[69],
                        a[70],a[71],a[72],b[73],a[74],b[75],b[76],a[77],b[78],a[79],
                        a[80],a[81],a[82],b[83],a[84],b[85],b[86],a[87],b[88],a[89],
                        a[90],a[91],a[92],b[93],a[94],b[95],b[96],a[97],b[98],a[99]
                    };
                    byteToImplement = byte1;
                    break;
                case 2:
                    byte[] byte2 = new byte[25] 
                    {
                        a[0], b[1], a[2], b[3], a[4], a[5], a[6], a[7], a[8], a[9],
                        a[10],b[11],b[12],b[13],a[14],a[15],a[16],a[17],a[18],a[19],
                        a[20],b[21],a[22],b[23],a[24]
                    };
                    byteToImplement = byte2;
                    break;
                case 3:
                    byte[] byte3 = new byte[25] 
                    {
                        a[0], a[1], a[2], a[3], b[4], a[5], a[6], a[7], a[8], a[9],
                        b[10],b[11],b[12],b[13],b[14],b[15],a[16],a[17],a[18],a[19],
                        a[20],a[21],a[22],a[23],b[24]
                    };
                    byteToImplement = byte3;
                    break;
                default:
                    byteToImplement = new byte[10];
                    break;

            }

            return byteToImplement;
        }

        //public void convert2grayscale(Bitmap source)
        //{
        //    Bitmap bm = new Bitmap(source.Width,source.Height);
        //    for(int y=0;y<bm.Height;y++)
        //    {
        //        for(int x=0;x<bm.Width;x++)
        //        {
        //            Color c=source.GetPixel(x,y);
        //            int luma = (int)(c.R*0.3 + c.G*0.59+ c.B*0.11);
        //            bm.SetPixel(x,y,Color.FromArgb(luma,luma,luma));   
        //        }
        //    }
        //    return bm;
        //}

        /// <summary>
        /// For Debug only- see function
        /// </summary>
        /// <param name="toDuplicate"></param>
        /// <param name="inPlaces"></param>
        /// <param name="finalByteArr"></param>
        public void InsertByteInPlaces(byte[] toDuplicate, int[] inPlaces, ref byte[] finalByteArr)
        {
            foreach (int a in inPlaces)
            {
                Buffer.BlockCopy(toDuplicate, 0, finalByteArr, a * toDuplicate.Length, toDuplicate.Length);
            }

        }
        #endregion
    }
}
